package com.servitware.cardio.dokstat.transport;

import java.io.*;
import java.net.SocketException;
import java.net.URL;
import java.security.InvalidParameterException;
import java.util.*;

import org.apache.commons.net.ftp.*;

import com.servitware.util.net.FtpWorkerError;
import com.servitware.util.net.ServerAbst;

// Referenced classes of package com.servitware.util.net:
//            FtpWorkerError, ServerAbst

public class FtpWorker
{

    private ServerAbst server;
    private FTPClient ftpClient;

    public FtpWorker(ServerAbst server)
    {
        ftpClient = new FTPClient();
        this.server = server;
    }

    protected ServerAbst getServer()
    {
        return server;
    }

    protected boolean openClient_Prefer_IPv4(FtpWorkerError ftpError)
        throws SocketException, IOException
    {
        boolean result = true;
        System.setProperty("java.net.preferIPv4Stack", "true");
        URL url = new URL(server.getServer());
        ftpClient.connect(url.getHost(), server.getPort().intValue());
        int reply = ftpClient.getReplyCode();
        ftpClient.getReplyString();
        if(ftpError == null)
        {
            ftpError = new FtpWorkerError(reply);
        } else
        {
            ftpError.setSrvReply(reply);
        }
        if(!FTPReply.isPositiveCompletion(reply))
        {
            ftpError.setResultNOK();
            try
            {
                ftpClient.disconnect();
            }
            catch(Exception e) { }
            return false;
        }
        if(!ftpClient.login(server.getUserName(), server.getPasswd()))
        {
            try
            {
                ftpClient.logout();
            }
            catch(Exception e) { }
            try
            {
                ftpClient.disconnect();
            }
            catch(Exception e) { }
            return false;
        } else
        {
            return result;
        }
    }

    protected void closeClient()
    {
        try
        {
            if(ftpClient != null && ftpClient.isConnected())
            {
                ftpClient.logout();
                ftpClient.disconnect();
                ftpClient = null;
            }
        }
        catch(IOException f) { }
    }

    protected boolean getFile(String file, File dir)
        throws FileNotFoundException, IOException
    {
    	
        
    	boolean result = true;
    	try{
        //ftpClient.setFileType(2);
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        
        ftpClient.enterLocalPassiveMode();
        File _file = new File(file);
        OutputStream output = new FileOutputStream((new StringBuilder()).append(dir.getAbsolutePath()).append(File.separator).append(_file.getName()).toString());
        result = ftpClient.retrieveFile(file, output);
        output.close();
    	}catch(Exception e){
    		e.printStackTrace();
    	}
        return result;
    }

    public boolean download(String file, File dir, FtpWorkerError srvReply)
        throws InvalidParameterException, SocketException, IOException
    {
        if(srvReply == null)
        {
            throw new InvalidParameterException("srvReply no puede ser nulo");
        }
        if(file == null)
        {
            throw new InvalidParameterException("Archivo a descargar no puede ser nulo");
        }
        if(dir == null || !dir.isDirectory())
        {
            throw new InvalidParameterException("Directorio destino no puede ser nulo, debe existir en FS y ser un directorio");
        } else
        {
            return getFile(file, dir);
        }
    }

    public List download(List files, File dir, FtpWorkerError srvReply)
        throws SocketException, IOException
    {
        List descargados = new ArrayList();
        if(files == null)
        {
            throw new InvalidParameterException("Lista archivos a descargar no puede ser nula");
        }
        if(dir == null || !dir.isDirectory())
        {
            throw new InvalidParameterException("Directorio destino no puede ser nulo, debe existir en FS y ser un directorio");
        }
        Iterator i$ = files.iterator();
        do
        {
            if(!i$.hasNext())
            {
                break;
            }
            String file = (String)i$.next();
            if(getFile(file, dir))
            {
                descargados.add(new File(file));
            }
        } while(true);
        return descargados;
    }

    public boolean upload(File localFile, String remoteFile, FtpWorkerError srvReply)
        throws SocketException, IOException
    {
        boolean result = true; 
        ftpClient.setFileType(2);
        ftpClient.enterLocalPassiveMode(); 
        InputStream input = new FileInputStream(localFile);
        File file = new File(remoteFile); 
        result = ftpClient.storeFile(remoteFile, input);
        input.close();
        return result;
    }

    
    /**
    * utility to create an arbitrary directory hierarchy on the remote ftp server 
    * @param client
    * @param dirTree  the directory tree only delimited with / chars.  No file name!
    * @throws Exception
    */
   /* private  void ftpCreateDirectoryTree( String dirTree ) throws IOException {

      boolean dirExists = true;

      //tokenize the string and attempt to change into each directory level.  If you cannot, then start creating.
      String[] directories = dirTree.split("/");
      for (String dir : directories ) {
        if (!dir.isEmpty() ) {
          if (dirExists) {
            dirExists = ftpClient.changeWorkingDirectory(dir);
          }
          if (!dirExists) {
            if (!ftpClient.makeDirectory(dir)) {
              throw new IOException("Unable to create remote directory '" + dir + "'.  error='" + ftpClient.getReplyString()+"'");
            }
            if (!ftpClient.changeWorkingDirectory(dir)) {
              throw new IOException("Unable to change into newly created remote directory '" + dir + "'.  error='" + ftpClient.getReplyString()+"'");
            }
          }
        }
      }     
    }*/
    
    public boolean dirExist(File dir)
        throws IOException
    {
        return ftpClient.cwd(dir.getPath()) == 250;
    }
    
    public boolean dirExist(String path)
            throws IOException
        {
            return ftpClient.cwd(path) == 250;
        }   
    
    public boolean fileExist(File file) throws IOException{

    	String rutaconvertida;
		if (file.getPath().indexOf("cardio")>0){
			rutaconvertida = file.getPath().replace("\\","/");			
		}else{
			rutaconvertida = file.getPath();			
		}
		
	    InputStream inputStream = ftpClient.retrieveFileStream(rutaconvertida);
	    int returnCode = ftpClient.getReplyCode();
	    if (inputStream == null || returnCode == 550) {
		    ftpClient.disconnect();
	        ftpClient = null;
	        return false;
	    }

	    ftpClient.disconnect();
        ftpClient = null;
	    return true;
	}
    
    protected boolean createDir(String dir)
        throws IOException
    {
        boolean result = false;
        File ftpDir = new File(dir);  
        if(dirExist(ftpDir))
        {
            return false;
        } else{
            result = ftpClient.makeDirectory(dir);
            return result;
        }
    }

    public FTPFile[] getDirList()
        throws IOException
    {
        ftpClient.configure(new FTPClientConfig("UNIX"));
        return ftpClient.listFiles();
    }
}
